import 'dart:math';

import 'package:flutter/material.dart';

class Test009 extends StatefulWidget {
  const Test009({super.key});

  @override
  State<Test009> createState() => _Test009State();
}

class _Test009State extends State<Test009> with SingleTickerProviderStateMixin {
  late AnimationController _controller;

  final List<Test009Snowflake> _snowflakes = List.generate(1000, (index) => Test009Snowflake());

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(vsync: this, duration: const Duration(seconds: 2));
    _controller.repeat();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("下雪动画"),
      ),
      body: Container(
        constraints: const BoxConstraints.expand(),
        decoration: const BoxDecoration(
          gradient: LinearGradient(
            begin: Alignment.topCenter,
            end: Alignment.bottomCenter,
            colors: [
              Colors.blue,
              Colors.lightBlue,
              Colors.white,
            ],
            stops: [0.0, 0.5, 1.0],
          ),
        ),
        child: AnimatedBuilder(
          animation: _controller,
          builder: (BuildContext context, Widget? child) {
            for (var snow in _snowflakes) {
              snow.fall();
            }
            return CustomPaint(
              painter: Test009CustomPaint(_snowflakes),
            );
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        child: const Icon(Icons.ads_click),
      ),
    );
  }
}

class Test009CustomPaint extends CustomPainter {
  final List<Test009Snowflake> _snowflakes;
  final Paint whitePaint = Paint()..color = Colors.white;

  Test009CustomPaint(this._snowflakes);

  @override
  void paint(Canvas canvas, Size size) {
    canvas.drawCircle(
      size.center(const Offset(0, 110)),
      60,
      whitePaint,
    );
    canvas.drawOval(
      Rect.fromCenter(
        center: size.center(const Offset(0, 280)),
        width: 200,
        height: 250,
      ),
      whitePaint,
    );
    for (var snowflake in _snowflakes) {
      canvas.drawCircle(
        Offset(snowflake.x, snowflake.y),
        snowflake.radius,
        whitePaint,
      );
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

class Test009Snowflake {
  double x = Random().nextDouble() * 400;
  double y = Random().nextDouble() * 800;
  double radius = Random().nextDouble() * 2 + 2;
  double velocity = Random().nextDouble() * 4 + 2;

  void fall() {
    y += velocity;
    if (y > 800) {
      y = 0;
      x = Random().nextDouble() * 400;
      radius = Random().nextDouble() * 2 + 2;
      velocity = Random().nextDouble() * 4 + 2;
    }
  }
}
